#include "socketthread.h"

socketThread::socketThread(QTcpSocket *socket, int num)
    : mySocket(socket)
    , num(num)
{
    mySocket->setParent(this);
    qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
    connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this, SLOT(onStateChanged(QAbstractSocket::SocketState)));
    connect(socket, SIGNAL(readyRead()), SLOT(onReadyRead()));
}

void socketThread::onStateChanged(QAbstractSocket::SocketState socketState)
{
    qDebug() << socketState;
    switch (socketState) {
    case QTcpSocket::ConnectedState:
        break;
    case QTcpSocket::UnconnectedState:
        emit signalDisconnect(num);
        break;
    default:
        break;
    }
}

void socketThread::onSendUpdateRequest()
{
    if (fileList.isEmpty()) {
        fileList = getDirAllFile("/home/xiaoxin/update");
    }

    TcpData tData;
    tData.type = Type::UPDATE;

    QJsonObject jo;
    jo.insert("versions", "1.0.1");
    jo.insert("connect", "本次更新内容为");
    QByteArray data = QJsonDocument(jo).toJson();
    tData.data = data;
    tData.fileData.fileName = QString(fileList.size()); //此处吧文件数量发送出去，客户端更新界面进度
    envelop(tData);
    envelop(tData);
}

void socketThread::onReadyRead()
{
    QByteArray data = mySocket->readAll();
    TcpData tData = unpack(data);
    switch (tData.type) {
    case Type::UPDATE:{
        startUpdate();
    }
        break;
    case Type::START:{
        startTransfer();
    }
        break;
    case Type::FINISH:{
        finish(tData);
    }
        break;
    default:
        break;
    }

}

QByteArray socketThread::envelop(TcpData data)
{
    qDebug() << data.type;
    QByteArray tempData;
    tempData = "$$$";
    tempData.append(data.type);
    tempData.append(data.data);
    tempData.append("|");
    tempData.append(data.fileData.fileName);
    tempData.append("|");
    tempData.append(data.fileData.MD5);
    tempData.append("|");
    tempData.append(data.fileData.fileContent);
    mySocket->write(tempData);
    mySocket->waitForBytesWritten();
    return tempData;
}

TcpData socketThread::unpack(QByteArray data)
{
    //qDebug() << data;
    TcpData tData;
    if (data.left(3) == "$$$") {
        data.remove(0, 3);
        tData.type = Type(data.left(1).toHex().toInt());
        data.remove(0, 1);
        //拆出头和状态后拆结构体
        QStringList dataList = QString(data).split("|");
        if (dataList.size() >= 4) {
            tData.data = dataList[0].toUtf8();
            tData.fileData.fileName = dataList[1];
            tData.fileData.MD5 = dataList[2];
            tData.fileData.fileContent = dataList[3].toUtf8();
        }
    }
    return tData;
}

void socketThread::startJsonEnvelop(TcpData data)
{

}

void socketThread::startJsonUnpack(QByteArray data)
{

}

const QString socketThread::countMd5(const QString filePath)
{
    if (QFileInfo(filePath).exists()) {
        QFile f(filePath);
        QByteArray fileData;
        if (f.open(QIODevice::ReadOnly)) {
            fileData = f.readAll();
            f.close();
        }
        QCryptographicHash cgh(QCryptographicHash::Md5);
        cgh.addData(fileData);
        return cgh.result().toHex();
    }
    return "";
}

const QStringList socketThread::getDirAllFile(QString path)
{
    if (!path.endsWith('/')) {
        path.append('/');
    }
    QDir dir(path);
    QStringList files;

    foreach (QString name, dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
        QString newPath = path + name;
        if (!QFileInfo(newPath).isSymLink() && QFileInfo(newPath).isDir()) {
            files.append(getDirAllFile(newPath));
        }
        files.append(newPath);
    }
    return files;
}

void socketThread::startUpdate()
{
    if (fileList.isEmpty()) {
        return;
    }
    qDebug() << fileList;
    TcpData tData;
    tData.type = Type::START;
    tData.data = "";
    tData.fileData.fileName = QFileInfo(fileList.at(0)).fileName();
    tData.fileData.MD5 = countMd5(fileList.at(0));
    envelop(tData);
}

void socketThread::startTransfer()
{
    if (fileList.isEmpty()) {
        return;
    }
    QFile f(fileList.at(0));
    if (f.open(QIODevice::ReadOnly)) {
        qint64 pos = 0;
        int size = 40000;
        TcpData tData;
        tData.type = Type::DATA;
        tData.fileData.fileName = QFileInfo(fileList.at(0)).fileName();
        qDebug() << f.size();
        //send File Data
        while (pos < f.size()) {
            tData.fileData.fileContent = f.read(size);
            pos += tData.fileData.fileContent.size();
            envelop(tData);
        }
        sendFinish();
    }
    else {

    }

}

void socketThread::finish(TcpData tData)
{
    qDebug() << "finish";
    if (fileList.isEmpty()) {
        //all File Transfer Finish

    }
    else {
        //可优化，结构体存储数据，外加重载==
        for (int i = 0; i < fileList.size(); ++i) {
            if (QFileInfo(fileList.at(i)).fileName() == tData.fileData.fileName) {
                fileList.removeAt(i);
                startUpdate();
                break;
            }
        }
    }
}

void socketThread::sendFinish()
{
    //send File Finish
    if (fileList.isEmpty()) {
        return;
    }
    TcpData tempData;
    tempData.type = Type::FINISH;
    tempData.fileData.fileContent.clear();
    tempData.fileData.MD5 = countMd5(fileList.at(0));
    tempData.fileData.fileName = QFileInfo(fileList.at(0)).fileName();
    envelop(tempData);
}
